#include <stdio.h>
#include <stdint.h>
#include <string.h>

typedef void (*ash_command)(int argc, char *argv[]);
typedef struct {
    ash_command cmd;
    char        alias[16];
} ash_command_t;

ash_command_t list_cmds[10] = {NULL};
static int    cnt           = 0;

#define EXPORT_ASH_COMMAND(func, description)                   \
    do {                                                        \
        printf("func addr=%x\n", func);                         \
        list_cmds[cnt].cmd = func;                              \
        snprintf(list_cmds[cnt].alias, 16, "%s", #description); \
        cnt++;                                                  \
    } while (0)

/**
 * @brief 注册ash命令
 *
 * @param cmd: 函数
 * @param alias: 函数别名
 */
void export_command(ash_command cmd, char *alias) {
    list_cmds[cnt].cmd = cmd;
    strncpy(list_cmds[cnt].alias, alias, 16);
    cnt++;
}

void cmd1(int argc, char *argv[]) {
    printf("cmd1\n");
    for (int i = 0; i < argc; ++i) {
        printf("%s ", argv[i]);
    }
    printf("\n");
}

void cmd2(int argc, char *argv[]) {
    printf("cmd2\n");
    for (int i = 0; i < argc; ++i) {
        printf("%s ", argv[i]);
    }
    printf("\n");
}

char *my_strdup(const char *s) {
    if (s == NULL) return NULL;
    size_t len  = strlen(s) + 1;
    char  *copy = malloc(len);
    if (copy != NULL) memcpy(copy, s, len);
    return copy;
}

char **split_string(const char *input, int *count) {
    // 去除末尾换行符（如果有）
    char *str = my_strdup(input);
    if (str == NULL) return NULL;
    str[strcspn(str, "\n")] = '\0';

    // 临时指针遍历字符串
    char *p   = str;
    int   len = strlen(p);

    // 预分配内存（可根据需求调整初始大小）
    int    capacity = 10;
    char **result   = malloc(capacity * sizeof(char *));
    if (result == NULL) {
        free(str);
        return NULL;
    }

    *count = 0;

    while (1) {
        // 跳过空格
        while (*p == ' ') p++;
        if (*p == '\0') break;

        // 记录子字符串起始位置
        char *start = p;

        // 找到下一个空格或结尾
        while (*p != ' ' && *p != '\0') p++;

        // 计算子字符串长度
        int substr_len = p - start;

        // 分配子字符串内存
        char *substr = malloc(substr_len + 1);
        if (substr == NULL) {
            // 内存不足时释放已分配的内存
            for (int i = 0; i < *count; i++) free(result[i]);
            free(result);
            free(str);
            return NULL;
        }

        // 复制子字符串
        strncpy(substr, start, substr_len);
        substr[substr_len] = '\0';

        // 动态扩展数组
        if (*count >= capacity) {
            capacity *= 2;
            char **temp = realloc(result, capacity * sizeof(char *));
            if (temp == NULL) {
                // 处理内存不足
                for (int i = 0; i < *count; i++) free(result[i]);
                free(result);
                free(str);
                return NULL;
            }
            result = temp;
        }

        result[(*count)++] = substr;
    }

    free(str);
    return result;
}

/**
 * @brief
 *
 */
void test01() {
    char *argv[2] = {"hello", "world"};
    export_command(cmd1, "cmd1");
    export_command(cmd2, "cmd2");

    EXPORT_ASH_COMMAND(cmd1, cmd1);
    // EXPORT_ASH_COMMAND(cmd2, cmd2);

    for (int i = 0; i < cnt; ++i) {
        list_cmds[i].cmd(2, argv);
    }
}

void test02(char *str) {
    int    my_argc = 0;
    char **my_argv = split_string(str, &my_argc);

    EXPORT_ASH_COMMAND(cmd1, cmd1);

    for (int i = 0; i < cnt; ++i) {
        if (strncmp(list_cmds[i].alias, my_argv[0], 16) == 0) {
            list_cmds[i].cmd(my_argc, my_argv);
        }
    }

    if (my_argv != NULL) {
        printf("分割结果（共 %d 项）:\n", my_argc);
        for (int i = 0; i < my_argc; i++) {
            printf("[%d] %s\n", i, my_argv[i]);
            free(my_argv[i]); // 释放每个子字符串
        }
        free(my_argv);        // 释放数组
    }
}

int main(int argc, char *argv[]) {
    // test01();
    test02("cmd1 hello world this is command\n");
    return 0;
}